"use strict";
var auth_token = {
    cipher: {}, hash: {}, keyexchange: {}, mode: {}, misc: {}, codec: {}, exception: {
        corrupt: function (a) {
            this.toString = function () {
                return "CORRUPT: " + this.message;
            };
            this.message = a;
        }, invalid: function (a) {
            this.toString = function () {
                return "INVALID: " + this.message;
            };
            this.message = a;
        }, bug: function (a) {
            this.toString = function () {
                return "BUG: " + this.message;
            };
            this.message = a;
        }, notReady: function (a) {
            this.toString = function () {
                return "NOT READY: " + this.message;
            };
            this.message = a;
        }
    }
};
"undefined" != typeof module && module.exports && (module.exports = auth_token);
auth_token.bitArray = {
    bitSlice: function (a, b, c) {
        a = auth_token.bitArray.g(a.slice(b / 32), 32 - (b & 31)).slice(1);
        return void 0 === c ? a : auth_token.bitArray.clamp(a, c - b)
    }, extract: function (a, b, c) {
        var d = Math.floor(-b - c & 31);
        return ((b + c - 1 ^ b) & -32 ? a[b / 32 | 0] << 32 - d ^ a[b / 32 + 1 | 0] >>> d : a[b / 32 | 0] >>> d) & (1 << c) - 1
    }, concat: function (a, b) {
        if (0 === a.length || 0 === b.length)return a.concat(b);
        var c = a[a.length - 1], d = auth_token.bitArray.getPartial(c);
        return 32 === d ? a.concat(b) : auth_token.bitArray.g(b, d, c | 0, a.slice(0, a.length - 1))
    }, bitLength: function (a) {
        var b = a.length;
        return 0 ===
        b ? 0 : 32 * (b - 1) + auth_token.bitArray.getPartial(a[b - 1])
    }, clamp: function (a, b) {
        if (32 * a.length < b)return a;
        a = a.slice(0, Math.ceil(b / 32));
        var c = a.length;
        b &= 31;
        0 < c && b && (a[c - 1] = auth_token.bitArray.partial(b, a[c - 1] & 2147483648 >> b - 1, 1));
        return a
    }, partial: function (a, b, c) {
        return 32 === a ? b : (c ? b | 0 : b << 32 - a) + 0x10000000000 * a
    }, getPartial: function (a) {
        return Math.round(a / 0x10000000000) || 32
    }, equal: function (a, b) {
        if (auth_token.bitArray.bitLength(a) !== auth_token.bitArray.bitLength(b))return !1;
        var c = 0, d;
        for (d = 0; d < a.length; d++)c |= a[d] ^ b[d];
        return 0 ===
            c
    }, g: function (a, b, c, d) {
        var e;
        e = 0;
        for (void 0 === d && (d = []); 32 <= b; b -= 32)d.push(c), c = 0;
        if (0 === b)return d.concat(a);
        for (e = 0; e < a.length; e++)d.push(c | a[e] >>> b), c = a[e] << 32 - b;
        e = a.length ? a[a.length - 1] : 0;
        a = auth_token.bitArray.getPartial(e);
        d.push(auth_token.bitArray.partial(b + a & 31, 32 < b + a ? c : d.pop(), 1));
        return d
    }, j: function (a, b) {
        return [a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]]
    }
};
auth_token.codec.base32 = {
    e: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", fromBits: function (a, b) {
        var c = "", d, e = 0, g = auth_token.codec.base32.e, f = 0, k = auth_token.bitArray.bitLength(a);
        for (d = 0; 5 * c.length < k;)c += g.charAt((f ^ a[d] >>> e) >>> 27), 5 > e ? (f = a[d] << 5 - e, e += 27, d++) : (f <<= 5, e -= 5);
        for (; c.length & 5 && !b;)c += "=";
        return c
    }, toBits: function (a) {
        a = a.replace(/\s|=/g, "").toUpperCase();
        var b = [], c, d = 0, e = auth_token.codec.base32.e, g = 0, f;
        for (c = 0; c < a.length; c++) {
            f = e.indexOf(a.charAt(c));
            if (0 > f)throw new auth_token.exception.invalid("this isn't base32!");
            27 < d ? (d -=
                27, b.push(g ^ f >>> d), g = f << 32 - d) : (d += 5, g ^= f << 32 - d)
        }
        d & 56 && b.push(auth_token.bitArray.partial(d & 56, g, 1));
        return b;
    }
};
auth_token.hash.sha1 = function (a) {
    a ? (this.d = a.d.slice(0), this.b = a.b.slice(0), this.a = a.a) : this.reset();
};
auth_token.hash.sha1.hash = function (a) {
    return (new auth_token.hash.sha1).update(a).finalize();
};
auth_token.hash.sha1.prototype = {
    blockSize: 512, reset: function () {
        this.d = this.h.slice(0);
        this.b = [];
        this.a = 0;
        return this;
    }, update: function (a) {
        "string" === typeof a && (a = auth_token.codec.utf8String.toBits(a));
        var b, c = this.b = auth_token.bitArray.concat(this.b, a);
        b = this.a;
        a = this.a = b + auth_token.bitArray.bitLength(a);
        for (b = this.blockSize + b & -this.blockSize; b <= a; b += this.blockSize)auth_token.n(this, c.splice(0, 16));
        return this;
    }, finalize: function () {
        var a, b = this.b, c = this.d, b = auth_token.bitArray.concat(b, [auth_token.bitArray.partial(1, 1)]);
        for (a = b.length + 2; a & 15; a++)b.push(0);
        b.push(Math.floor(this.a / 0x100000000));
        for (b.push(this.a | 0); b.length;)auth_token.n(this, b.splice(0, 16));
        this.reset();
        return c;
    }, h: [1732584193, 4023233417, 2562383102, 271733878, 3285377520], i: [1518500249, 1859775393, 2400959708, 3395469782]
}
auth_token.n = function (a, b) {
    var c, d, e, g, f, k, m, l = b.slice(0), h = a.d;
    e = h[0];
    g = h[1];
    f = h[2];
    k = h[3];
    m = h[4];
    for (c = 0; 79 >= c; c++)16 <= c && (l[c] = (l[c - 3] ^ l[c - 8] ^ l[c - 14] ^ l[c - 16]) << 1 | (l[c - 3] ^ l[c - 8] ^ l[c - 14] ^ l[c - 16]) >>> 31), d = 19 >= c ? g & f | ~g & k : 39 >= c ? g ^ f ^ k : 59 >= c ? g & f | g & k | f & k : 79 >= c ? g ^ f ^ k : void 0, d = (e << 5 | e >>> 27) + d + m + l[c] + a.i[Math.floor(c / 20)] | 0, m = k, k = f, f = g << 30 | g >>> 2, g = e, e = d;
    h[0] = h[0] + e | 0;
    h[1] = h[1] + g | 0;
    h[2] = h[2] + f | 0;
    h[3] = h[3] + k | 0;
    h[4] = h[4] + m | 0
}
auth_token.misc.hmac = function (a, b) {
    this.f = b = b || auth_token.hash.sha256;
    var c = [[], []], d, e = b.prototype.blockSize / 32;
    this.c = [new b, new b];
    a.length > e && (a = b.hash(a));
    for (d = 0; d < e; d++)c[0][d] = a[d] ^ 909522486, c[1][d] = a[d] ^ 1549556828;
    this.c[0].update(c[0]);
    this.c[1].update(c[1]);
};
auth_token.misc.hmac.prototype.encrypt = auth_token.misc.hmac.prototype.mac = function (a) {
    a = (new this.f(this.c[0])).update(a).finalize();
    return (new this.f(this.c[1])).update(a).finalize();
};

//获取动态口令
var getAuthToken = auth_token.getAuthToken = function (token, C) {
    var key = auth_token.codec.base32.toBits(token);
    var count = [((C & 0xffffffff00000000) >> 32), C & 0xffffffff];
    var otplength = 6;
    var hmacsha1 = new auth_token.misc.hmac(key, auth_token.hash.sha1);
    var code = hmacsha1.encrypt(count);
    var offset = auth_token.bitArray.extract(code, 152, 8) & 0x0f;
    var startBits = offset * 8;
    var endBits = startBits + 4 * 8;
    var slice = auth_token.bitArray.bitSlice(code, startBits, endBits);
    var dbc1 = slice[0];
    var dbc2 = dbc1 & 0x7fffffff;
    var otp = dbc2 % Math.pow(10, otplength);
    var result = otp.toString();
    while (result.length < otplength) {
        result = '0' + result;
    }
    return result;
};
//获取动态口令值 token : 口令，c:误差时效 单位 分钟
var getAuthToken_s = auth_token.getAuthToken_s = function (token, private_token, c) {
    return getAuthToken(token, (new Date().getTime() / 1000 / 60 / c).toFixed(0).toString() + private_token);
};
//获取5分钟误差时效的动态口令值 token : 口令
var getAuthToken_5minute = auth_token.getAuthToken_5minute = function (token, private_token) {
    return getAuthToken_s(token, private_token, 5);
};
//获取5分钟误差时效的动态口令值 token : 口令
var getAuthToken_30minute = auth_token.getAuthToken_30minute = function (token, private_token) {
    return getAuthToken_s(token, private_token, 30);
};